package com.example.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.constants.WmNewsMessageConstants;
import com.example.common.exception.CustomException;
import com.example.model.acl.pojos.Acl_user;
import com.example.model.common.dtos.PageResponseResult;
import com.example.model.common.dtos.ResponseResult;
import com.example.model.common.enums.AppHttpCodeEnum;
import com.example.model.wemedia.dtos.WmNewsDto;
import com.example.model.wemedia.dtos.WmNewsPageReqDto;
import com.example.model.wemedia.pojos.WmChannel;
import com.example.model.wemedia.pojos.WmMaterial;
import com.example.model.wemedia.pojos.WmNews;
import com.example.model.wemedia.pojos.WmNewsMaterial;
import com.example.user.mapper.AclUserMapper;
import com.example.wemedia.mapper.WmChannelMapper;
import com.example.wemedia.mapper.WmMaterialMapper;
import com.example.wemedia.mapper.WmNewsMapper;
import com.example.wemedia.mapper.WmNewsMaterialMapper;
import com.example.wemedia.service.WmChannelService;
import com.example.wemedia.service.WmNewsAutoScanService;
import com.example.wemedia.service.WmNewsService;
import com.example.wemedia.service.WmNewsTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl  extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmChannelService wmChannelService;

    @Autowired
    private WmChannelMapper wmChannelMapper;

    @Autowired
    private WmNewsTaskService wmNewsTaskService;

    @Override
    public ResponseResult findNewsList(WmNewsPageReqDto dto, String userId) {
        dto.checkParam();

        IPage page = new Page(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        log.info("status1 {}",dto.getStatus());
        if(dto.getStatus() != null){
            if(dto.getStatus() != -1){
                log.info("status2 {}",dto.getStatus());
                lambdaQueryWrapper.eq(WmNews::getStatus,dto.getStatus());
            }

        }
        if(dto.getChannelId() != null){
            lambdaQueryWrapper.eq(WmNews::getChannelId,dto.getChannelId());
        }
        if(dto.getBeginPubDate() != null && dto.getEndPubDate() != null){
            lambdaQueryWrapper.between(WmNews::getPublishTime,dto.getBeginPubDate(),dto.getEndPubDate());
        }
        if(StringUtils.isNotEmpty(dto.getKeyword())){
            lambdaQueryWrapper.like(WmNews::getTitle,dto.getKeyword());
        }
        lambdaQueryWrapper.eq(WmNews::getUserId,userId);
        lambdaQueryWrapper.orderByDesc(WmNews::getPublishTime);

        page = page(page,lambdaQueryWrapper);
        ResponseResult responseResult = new PageResponseResult(dto.getPage(),dto.getSize(), (int) page.getTotal());
        responseResult.setData(page.getRecords());
        return responseResult;
    }

    @Override
    public ResponseResult deleteOneMyArticle(String id,String userId) {
        LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WmNews::getId,id)
                .eq(WmNews::getUserId,userId);

        LambdaQueryWrapper<WmNewsMaterial> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(WmNewsMaterial::getNewsId,id);
        wmNewsMaterialMapper.delete(lambdaQueryWrapper1);

        wmNewsMapper.delete(lambdaQueryWrapper);
        return ResponseResult.okResult("删除成功");
    }

    @Autowired
    private WmNewsAutoScanService wmNewsAutoScanService;



    @Override
    public ResponseResult submit(WmNewsDto wmNewsDto,String userId) {
        if(wmNewsDto == null || wmNewsDto.getContent() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

//        Acl_user acl_user = aclUserMapper.selectById(userId);

        //1.保存或修改文章
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(wmNewsDto,wmNews);
        //此处图片属性都是String images;
        //不考虑自动这种情况
        wmNews.setSubmitedTime(new Date());

        WmNews object = saveOrUpdateNews(wmNews,userId);
        wmNews.setId(object.getId());

        //如果是草稿，结束当前方法
        if(wmNewsDto.getStatus().equals(WmNews.Status.NORMAL.getCode())){
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }

        //不是草稿
        //获取内容中的图片信息
        List<String> materials = getUrlInfo(wmNewsDto.getContent());
        //保存文章内容图片与素材的关系
        saveRelationsForContent(materials,wmNews.getId());

        //保存文章封面图片与素材的关系
        saveRelationsForCover(wmNewsDto,wmNews);

        //wmNewsAutoScanService.autoScanNews(wmNews.getId());
        log.info("wmNews.getPublishTime() {}",wmNews.getPublishTime());
        wmNewsTaskService.addNewsToTask(wmNews.getId(),wmNews.getPublishTime());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult getChannels() {
        List<WmChannel> channels = wmChannelService.list();
        List<Map<String,Object>> object = channels.stream().map(
                channel->{
                    Map<String, Object> map = new HashMap<>();
                    map.put("channelId", channel.getId());
                    map.put("name", channel.getName());
                    // 将其他需要的属性添加到 Map 中
                    return map;
                }
        ).collect(Collectors.toList());
        return ResponseResult.okResult(object);
    }

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Override
    public ResponseResult downOrUp(WmNewsDto wmNewsDto) {
        if(wmNewsDto.getId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = getById(wmNewsDto.getId());
        if(wmNews == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        if(!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"当前文章不是发布状态");
        }

        if(wmNews.getEnable() != null && wmNews.getEnable() > -1 && wmNews.getEnable() < 2){
            update(Wrappers.<WmNews>lambdaUpdate().set(WmNews::getEnable,wmNewsDto.getEnable())
                    .eq(WmNews::getId,wmNews.getId()));

            if(wmNews.getArticleId()!=null){
                Map<String ,Object> map = new HashMap<>();
                map.put("articleId",wmNews.getArticleId());
                map.put("enable",wmNewsDto.getEnable());
                kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JSON.toJSONString(map));
            }

        }


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     *
     * @param wmNewsDto
     * @param wmNews
     */
    private void saveRelationsForCover(WmNewsDto wmNewsDto, WmNews wmNews) {
        String image = wmNews.getImages();
        List<String> images = new ArrayList<>();
        images.add(image);
        saveRelationsInfo(images, wmNews.getId(), 1);
    }

    private void saveRelationsForContent(List<String> materials, Integer newsId) {
        //0代表内容 1代表封面
        saveRelationsInfo(materials,newsId,0);
    }

    //保存文章封面/内容图片与素材的关系
    private void saveRelationsInfo(List<String> materials, Integer newsId, int i) {

        if(materials != null && !materials.isEmpty()){
            //通过url查找ids
            List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, materials));
            if(wmMaterials == null || wmMaterials.isEmpty()){
                throw new CustomException(AppHttpCodeEnum.MATERIAL_REFERENCE_FAIL);
            }
            if(wmMaterials.size() != materials.size()){
                throw new CustomException(AppHttpCodeEnum.MATERIAL_REFERENCE_FAIL);
            }
            List<Integer> collect = wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
            wmNewsMaterialMapper.saveRelations(collect,newsId, (short) i);
        }

    }

    private List<String> getUrlInfo(String content) {
        List<String> materials = new ArrayList<>();
        List<Map> maps = JSON.parseArray(content, Map.class);
        for (Map map : maps) {
            if(map.get("type").equals("image")){
                String imgUrl = (String) map.get("value");
                materials.add(imgUrl);
            }
        }
        return materials;
    }

    private WmNews saveOrUpdateNews(WmNews wmNews,String userId) {
        wmNews.setUserId(Integer.valueOf(userId));
        wmNews.setCreatedTime(new Date());
        wmNews.setPublishTime(new Date());
        wmNews.setEnable((short)1);

        if(wmNews.getId() == null){
            //保存操作
            save(wmNews);
        }else{
            //修改操作
            //删除文章图片与素材的关系
            LambdaQueryWrapper<WmNewsMaterial> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(WmNewsMaterial::getNewsId,wmNews.getId());
            wmNewsMaterialMapper.delete(lambdaQueryWrapper);
            updateById(wmNews);
        }
        System.out.println("userId "+wmNews.getUserId());
        System.out.println("title "+wmNews.getTitle());
        WmNews object = wmNewsMapper.selectOne(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getUserId, wmNews.getUserId()).eq(WmNews::getTitle, wmNews.getTitle()));
        return object;
    }
}
